home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / lib / emacs / 19.22 / lisp / paren.el < prev    next >
Lisp/Scheme  |  1993-08-11  |  5KB  |  142 lines

  1. ;;; paren.el --- highlight matching paren.
  2. ;; Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. ;; Author: rms@gnu.ai.mit.edu
  5. ;; Maintainer: FSF
  6. ;; Keywords: languages, faces
  7.  
  8. ;; This file is part of GNU Emacs.
  9.  
  10. ;; GNU Emacs is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14.  
  15. ;; GNU Emacs is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;; GNU General Public License for more details.
  19.  
  20. ;; You should have received a copy of the GNU General Public License
  21. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  22. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24. ;;; Commentary:
  25.  
  26. ;; Load this and it will display highlighting on whatever
  27. ;; paren matches the one before or after point.
  28.  
  29. ;;; Code:
  30.  
  31. ;; This is the overlay used to highlight the matching paren.
  32. (defvar show-paren-overlay nil)
  33. ;; This is the overlay used to highlight the closeparen
  34. ;; right before point.
  35. (defvar show-paren-overlay-1 nil)
  36.  
  37. (defvar show-paren-mismatch-face nil)
  38.  
  39. (defvar show-paren-face 'region
  40.   "*Name of face to use for showing the matching paren.")
  41.  
  42. ;; Find the place to show, if there is one,
  43. ;; and show it until input arrives.
  44. (defun show-paren-command-hook ()
  45.   ;; Do nothing if no window system to display results with.
  46.   ;; Do nothing if input is pending.
  47.   (if (and window-system (sit-for 0))
  48.       (let (pos dir mismatch (oldpos (point))
  49.         (face show-paren-face))
  50.     (cond ((eq (char-syntax (following-char)) ?\()
  51.            (setq dir 1))
  52.           ((eq (char-syntax (preceding-char)) ?\))
  53.            (setq dir -1)))
  54.     (if dir
  55.         (save-excursion
  56.           (save-restriction
  57.         ;; Determine the range within which to look for a match.
  58.         (if blink-matching-paren-distance
  59.             (narrow-to-region (max (point-min)
  60.                        (- (point) blink-matching-paren-distance))
  61.                       (min (point-max)
  62.                        (+ (point) blink-matching-paren-distance))))
  63.         ;; Scan across one sexp within that range.
  64.         (condition-case ()
  65.             (setq pos (scan-sexps (point) dir))
  66.           (error nil))
  67.         ;; See if the "matching" paren is the right kind of paren
  68.         ;; to match the one we started at.
  69.         (if pos
  70.             (let ((beg (min pos oldpos)) (end (max pos oldpos)))
  71.               (and (/= (char-syntax (char-after beg)) ?\$)
  72.                (setq mismatch
  73.                  (/= (char-after (1- end))
  74.                      (logand (lsh (aref (syntax-table)
  75.                             (char-after beg))
  76.                           -8)
  77.                          255))))))
  78.         ;; If they don't properly match, use a different face,
  79.         ;; or print a message.
  80.         (if mismatch
  81.             (progn
  82.               (and (null show-paren-mismatch-face)
  83.                (x-display-color-p)
  84.                (or (setq show-paren-mismatch-face
  85.                      (internal-find-face 'paren-mismatch))
  86.                    (progn
  87.                  (make-face 'paren-mismatch)
  88.                  (setq show-paren-mismatch-face
  89.                        'paren-mismatch)
  90.                  (set-face-background 'paren-mismatch
  91.                               "purple"))))
  92.               (if show-paren-mismatch-face
  93.               (setq face show-paren-mismatch-face)
  94.             (message "Paren mismatch"))))
  95.         )))
  96.     (cond (pos
  97.            (if (= dir -1)
  98.            ;; If matching backwards, highlight the closeparen
  99.            ;; before point as well as its matching open.
  100.            (progn
  101.              (if show-paren-overlay-1
  102.              (move-overlay show-paren-overlay-1
  103.                        (+ (point) dir) (point)
  104.                        (current-buffer))
  105.                (setq show-paren-overlay-1
  106.                  (make-overlay (- pos dir) pos)))
  107.              (overlay-put show-paren-overlay-1 'face face))
  108.          ;; Otherwise, turn off any such highlighting.
  109.          (and show-paren-overlay-1
  110.               (overlay-buffer show-paren-overlay-1)
  111.               (delete-overlay show-paren-overlay-1)))
  112.            ;; Turn on highlighting for the matching paren.
  113.            (if show-paren-overlay
  114.            (move-overlay show-paren-overlay (- pos dir) pos
  115.                  (current-buffer))
  116.          (setq show-paren-overlay
  117.                (make-overlay (- pos dir) pos)))
  118.            (overlay-put show-paren-overlay 'face face))
  119.           (t
  120.            ;; If not at a paren that has a match,
  121.            ;; turn off any previous paren highlighting.
  122.            (and show-paren-overlay (overlay-buffer show-paren-overlay)
  123.             (delete-overlay show-paren-overlay))
  124.            (and show-paren-overlay-1 (overlay-buffer show-paren-overlay-1)
  125.             (delete-overlay show-paren-overlay-1)))))))
  126.  
  127. (if window-system
  128.     (progn
  129.       (setq blink-paren-function nil)
  130.       (add-hook 'post-command-hook 'show-paren-command-hook)))
  131. ;;; This is in case paren.el is preloaded.
  132. (add-hook 'window-setup-hook
  133.       (function (lambda ()
  134.               (if window-system
  135.               (progn
  136.                 (setq blink-paren-function nil)
  137.                 (add-hook 'post-command-hook
  138.                       'show-paren-command-hook))))))
  139. (provide 'paren)
  140.  
  141. ;;; paren.el ends here
  142.